package cn.pzx.main_module.ui.activity

import android.content.pm.ActivityInfo
import android.graphics.Canvas
import android.view.View
import android.view.animation.AccelerateInterpolator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import cn.pzx.base_module.base.BaseActivity
import cn.pzx.main_module.R
import cn.pzx.main_module.databinding.ActivityPostBinding
import cn.pzx.main_module.interfaces.DragListener
import cn.pzx.main_module.picselectengine.GlideEngine
import cn.pzx.main_module.ui.adapter.GridImageAdapter
import cn.pzx.main_module.ui.layoutmanger.FullyGridLayoutManager
import cn.pzx.main_module.ui.vm.PostActivityVM
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.luck.picture.lib.PictureSelector
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.decoration.GridSpacingItemDecoration
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.listener.OnResultCallbackListener
import com.luck.picture.lib.tools.ScreenUtils
import com.luck.picture.lib.tools.SdkVersionUtils
import kotlinx.android.synthetic.main.view_layout_number.view.*
import java.lang.ref.WeakReference
import java.util.*


/**
 * @author pzx
 * @description:
 * @date :3/18/21 11:15 AM
 */
class PostActivity : BaseActivity<PostActivityVM, ActivityPostBinding>() {

    companion object {

        val TAG: String = PostActivity::class.java.getSimpleName()

    }

    var maxSelectNum = 9
    var mAdapter: GridImageAdapter? = null

    private var isUpward = false
    private var needScaleBig = true
    private var needScaleSmall = true


    private var mItemTouchHelper: ItemTouchHelper? = null
    private var mDragListener: DragListener? = null

    override fun initView() {
        initPermission()

        vb.root.tv_select_num.text = 8.toString()
        vb.recycler.layoutManager =
            FullyGridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false)

        mAdapter = GridImageAdapter(this, GridImageAdapter.onAddPicClickListener {


            // 进入相册 以下是例子：不需要的api可以不写
            PictureSelector.create(this@PostActivity)
                .openGallery(PictureMimeType.ofAll()) // 全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
                .imageEngine(GlideEngine.createGlideEngine()) // 外部传入图片加载引擎，必传项
                //.theme(themeId)// 主题样式设置 具体参考 values/styles   用法：R.style.picture.white.style v2.3.3后 建议使用setPictureStyle()动态方式
                //                .setPictureUIStyle(mSelectorUIStyle) //.setPictureStyle(mPictureParameterStyle)// 动态自定义相册主题
                //.setPictureCropStyle(mCropParameterStyle)// 动态自定义裁剪主题
                //                .setPictureWindowAnimationStyle(mWindowAnimationStyle) // 自定义相册启动退出动画
                .isWeChatStyle(true) // 是否开启微信图片选择风格
                //                .isUseCustomCamera(cb_custom_camera.isChecked()) // 是否使用自定义相机
                //                .setLanguage(language) // 设置语言，默认中文
                //                    .isPageStrategy(cbPage.isChecked()) // 是否开启分页策略 & 每页多少条；默认开启
                //                    .setRecyclerAnimationMode(animationMode) // 列表动画效果
                .isWithVideoImage(true) // 图片和视频是否可以同选,只在ofAll模式下有效
                //                    .isMaxSelectEnabledMask(cbEnabledMask.isChecked()) // 选择数到了最大阀值列表是否启用蒙层效果
                //.isAutomaticTitleRecyclerTop(false)// 连续点击标题栏RecyclerView是否自动回到顶部,默认true
                //.loadCacheResourcesCallback(GlideCacheEngine.createCacheEngine())// 获取图片资源缓存，主要是解决华为10部分机型在拷贝文件过多时会出现卡的问题，这里可以判断只在会出现一直转圈问题机型上使用
                //.setOutputCameraPath(createCustomCameraOutPath())// 自定义相机输出目录
                //.setButtonFeatures(CustomCameraView.BUTTON_STATE_BOTH)// 设置自定义相机按钮状态
                .maxSelectNum(maxSelectNum) // 最大图片选择数量
                .minSelectNum(1) // 最小选择数量
                .maxVideoSelectNum(1) // 视频最大选择数量
                //.minVideoSelectNum(1)// 视频最小选择数量
                //.closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q())// 关闭在AndroidQ下获取图片或视频宽高相反自动转换
                .imageSpanCount(4) // 每行显示个数
                .isReturnEmpty(false) // 未选择数据时点击按钮是否可以返回
                .closeAndroidQChangeWH(true) //如果图片有旋转角度则对换宽高,默认为true
                .closeAndroidQChangeVideoWH(!SdkVersionUtils.checkedAndroid_Q()) // 如果视频有旋转角度则对换宽高,默认为false
                //.isAndroidQTransform(true)// 是否需要处理Android Q 拷贝至应用沙盒的操作，只针对compress(false); && .isEnableCrop(false);有效,默认处理
                .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) // 设置相册Activity方向，不设置默认使用系统
                //                    .isOriginalImageControl(cb_original.isChecked()) // 是否显示原图控制按钮，如果设置为true则用户可以自由选择是否使用原图，压缩、裁剪功能将会失效
                //.bindCustomPlayVideoCallback(new MyVideoSelectedPlayCallback(getContext()))// 自定义视频播放回调控制，用户可以使用自己的视频播放界面
                //.bindCustomPreviewCallback(new MyCustomPreviewInterfaceListener())// 自定义图片预览回调接口
                //.bindCustomCameraInterfaceListener(new MyCustomCameraInterfaceListener())// 提供给用户的一些额外的自定义操作回调
                //.cameraFileName(System.currentTimeMillis() +".jpg")    // 重命名拍照文件名、如果是相册拍照则内部会自动拼上当前时间戳防止重复，注意这个只在使用相机时可以使用，如果使用相机又开启了压缩或裁剪 需要配合压缩和裁剪文件名api
                //.renameCompressFile(System.currentTimeMillis() +".jpg")// 重命名压缩文件名、 如果是多张压缩则内部会自动拼上当前时间戳防止重复
                //.renameCropFileName(System.currentTimeMillis() + ".jpg")// 重命名裁剪文件名、 如果是多张裁剪则内部会自动拼上当前时间戳防止重复
                //                    .selectionMode(if (cb_choose_mode.isChecked()) PictureConfig.MULTIPLE else PictureConfig.SINGLE) // 多选 or 单选
                //                    .isSingleDirectReturn(cb_single_back.isChecked()) // 单选模式下是否直接返回，PictureConfig.SINGLE模式下有效
                //                    .isPreviewImage(cb_preview_img.isChecked()) // 是否可预览图片
                //                    .isPreviewVideo(cb_preview_video.isChecked()) // 是否可预览视频
                //.querySpecifiedFormatSuffix(PictureMimeType.ofJPEG())// 查询指定后缀格式资源
                //                    .isEnablePreviewAudio(cb_preview_audio.isChecked()) // 是否可播放音频
                //                    .isCamera(cb_isCamera.isChecked()) // 是否显示拍照按钮
                //.isMultipleSkipCrop(false)// 多图裁剪时是否支持跳过，默认支持
                //.isMultipleRecyclerAnimation(false)// 多图裁剪底部列表显示动画效果
                .isZoomAnim(true) // 图片列表点击 缩放效果 默认true
                //.imageFormat(PictureMimeType.PNG)// 拍照保存图片格式后缀,默认jpeg,Android Q使用PictureMimeType.PNG_Q
                //                    .isEnableCrop(cb_crop.isChecked()) // 是否裁剪
                //.basicUCropConfig()//对外提供所有UCropOptions参数配制，但如果PictureSelector原本支持设置的还是会使用原有的设置
                //                    .isCompress(cb_compress.isChecked()) // 是否压缩
                //.compressQuality(80)// 图片压缩后输出质量 0~ 100
                .synOrAsy(false) //同步true或异步false 压缩 默认同步
                //.queryMaxFileSize(10)// 只查多少M以内的图片、视频、音频  单位M
                //.compressSavePath(getPath())//压缩图片保存地址
                //.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效 注：已废弃
                //.glideOverride(160, 160)// glide 加载宽高，越小图片列表越流畅，但会影响列表图片浏览的清晰度 注：已废弃
                //                    .withAspectRatio(aspect_ratio_x, aspect_ratio_y) // 裁剪比例 如16:9 3:2 3:4 1:1 可自定义
                //                    .hideBottomControls(!cb_hide.isChecked()) // 是否显示uCrop工具栏，默认不显示
                //                    .isGif(cb_isGif.isChecked()) // 是否显示gif图片
                //.isWebp(false)// 是否显示webp图片,默认显示
                //.isBmp(false)//是否显示bmp图片,默认显示
                //                    .freeStyleCropEnabled(cb_styleCrop.isChecked()) // 裁剪框是否可拖拽
                //                    .circleDimmedLayer(cb_crop_circular.isChecked()) // 是否圆形裁剪
                //.setCropDimmedColor(ContextCompat.getColor(getContext(), R.color.app_color_white))// 设置裁剪背景色值
                //.setCircleDimmedBorderColor(ContextCompat.getColor(getApplicationContext(), R.color.app_color_white))// 设置圆形裁剪边框色值
                //.setCircleStrokeWidth(3)// 设置圆形裁剪边框粗细
                //                    .showCropFrame(cb_showCropFrame.isChecked()) // 是否显示裁剪矩形边框 圆形裁剪时建议设为false
                //                    .showCropGrid(cb_showCropGrid.isChecked()) // 是否显示裁剪矩形网格 圆形裁剪时建议设为false
                //                    .isOpenClickSound(cb_voice.isChecked()) // 是否开启点击声音
                .selectionData(mAdapter?.getData()) // 是否传入已选图片
                //.isDragFrame(false)// 是否可拖动裁剪框(固定)
                //.videoMinSecond(10)// 查询多少秒以内的视频
                //.videoMaxSecond(15)// 查询多少秒以内的视频
                //.recordVideoSecond(10)//录制视频秒数 默认60s
                //.isPreviewEggs(true)// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中)
                //.cropCompressQuality(90)// 注：已废弃 改用cutOutQuality()
                .cutOutQuality(90) // 裁剪输出质量 默认100
                .minimumCompressSize(100) // 小于多少kb的图片不压缩
                //.cropWH()// 裁剪宽高比，设置如果大于图片本身宽高则无效
                //.cropImageWideHigh()// 裁剪宽高比，设置如果大于图片本身宽高则无效
                //.rotateEnabled(false) // 裁剪是否可旋转图片
                //.scaleEnabled(false)// 裁剪是否可放大缩小图片
                //.videoQuality()// 视频录制质量 0 or 1
                //.forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code
                .forResult(MyResultCallback(mAdapter))


        })
        vb.recycler.adapter = mAdapter

        vb.recycler.addItemDecoration(
            GridSpacingItemDecoration(
                4,
                ScreenUtils.dip2px(this, 8f), false
            )
        )


        mAdapter!!.setSelectMax(maxSelectNum)
        mAdapter!!.setItemLongClickListener { holder, position, v ->
            //如果item不是最后一个，则执行拖拽
            needScaleBig = true
            needScaleSmall = true
            val size: Int = mAdapter!!.data.size
            if (size != maxSelectNum) {
                mItemTouchHelper?.startDrag(holder)
                return@setItemLongClickListener
            }
            if (holder.layoutPosition !== size - 1) {
                mItemTouchHelper?.startDrag(holder)
            }
        }

        mDragListener = object : DragListener {
            override fun deleteState(isDelete: Boolean) {
                if (isDelete) {
                    vb.tvDeleteText.setText("松手即可删除")
                    vb.tvDeleteText.setCompoundDrawablesRelativeWithIntrinsicBounds(
                        0,
                        R.mipmap.ic_let_go_delete,
                        0,
                        0
                    )
                } else {
                    vb.tvDeleteText.setText("拖到这里删除")
                    vb.tvDeleteText.setCompoundDrawablesRelativeWithIntrinsicBounds(
                        0,
                        R.drawable.picture_icon_delete,
                        0,
                        0
                    )
                }
            }

            override fun dragState(isStart: Boolean) {
                val visibility: Int = vb.tvDeleteText.getVisibility()
                if (isStart) {
                    if (visibility == View.GONE) {
                        vb.tvDeleteText.animate().alpha(1f).setDuration(300)
                            .setInterpolator(AccelerateInterpolator())
                        vb.tvDeleteText.setVisibility(View.VISIBLE)
                    }
                } else {
                    if (visibility == View.VISIBLE) {
                        vb.tvDeleteText.animate().alpha(0f).setDuration(300)
                            .setInterpolator(AccelerateInterpolator())
                        vb.tvDeleteText.setVisibility(View.GONE)
                    }
                }
            }
        }

        mItemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
            override fun isLongPressDragEnabled(): Boolean {
                return true
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
            override fun getMovementFlags(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder
            ): Int {
                val itemViewType = viewHolder.itemViewType
                if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
                    viewHolder.itemView.alpha = 0.7f
                }
                return makeMovementFlags(
                    ItemTouchHelper.DOWN or ItemTouchHelper.UP
                            or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT, 0
                )
            }

            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean {
                //得到item原来的position
                try {
                    val fromPosition = viewHolder.adapterPosition
                    //得到目标position
                    val toPosition = target.adapterPosition
                    val itemViewType = target.itemViewType
                    if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
                        if (fromPosition < toPosition) {
                            for (i in fromPosition until toPosition) {
                                Collections.swap(mAdapter!!.data, i, i + 1)
                            }
                        } else {
                            for (i in fromPosition downTo toPosition + 1) {
                                Collections.swap(mAdapter!!.data, i, i - 1)
                            }
                        }
                        mAdapter!!.notifyItemMoved(fromPosition, toPosition)
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                return true
            }

            override fun onChildDraw(
                c: Canvas,
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                dX: Float,
                dY: Float,
                actionState: Int,
                isCurrentlyActive: Boolean
            ) {
                val itemViewType = viewHolder.itemViewType
                if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
                    if (null == mDragListener) {
                        return
                    }
                    if (needScaleBig) {
                        //如果需要执行放大动画
                        viewHolder.itemView.animate().scaleXBy(0.1f).scaleYBy(0.1f).duration = 100
                        //执行完成放大动画,标记改掉
                        needScaleBig = false
                        //默认不需要执行缩小动画，当执行完成放大 并且松手后才允许执行
                        needScaleSmall = false
                    }

                    val sh: Int = recyclerView.height + vb.tvDeleteText.getHeight()
                    val ry: Int = vb.tvDeleteText.getBottom() - sh
                    if (dY >= ry) {
                        //拖到删除处
                        mDragListener?.deleteState(true)
                        if (isUpward) {
                            //在删除处放手，则删除item
                            viewHolder.itemView.visibility = View.INVISIBLE
                            mAdapter!!.delete(viewHolder.adapterPosition)
                            resetState()
                            return
                        }
                    } else { //没有到删除处
                        if (View.INVISIBLE == viewHolder.itemView.visibility) {
                            //如果viewHolder不可见，则表示用户放手，重置删除区域状态
                            mDragListener?.dragState(false)
                        }
                        if (needScaleSmall) { //需要松手后才能执行
                            viewHolder.itemView.animate().scaleXBy(1f).scaleYBy(1f).duration = 100
                        }
                        mDragListener?.deleteState(false)
                    }
                    super.onChildDraw(
                        c,
                        recyclerView,
                        viewHolder,
                        dX,
                        dY,
                        actionState,
                        isCurrentlyActive
                    )
                }
            }

            override fun onSelectedChanged(
                viewHolder: RecyclerView.ViewHolder?,
                actionState: Int
            ) {
                val itemViewType =
                    viewHolder?.itemViewType ?: GridImageAdapter.TYPE_CAMERA
                if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
                    if (ItemTouchHelper.ACTION_STATE_DRAG == actionState && mDragListener != null) {
                        mDragListener?.dragState(true)
                    }
                    super.onSelectedChanged(viewHolder, actionState)
                }
            }

            override fun getAnimationDuration(
                recyclerView: RecyclerView,
                animationType: Int,
                animateDx: Float,
                animateDy: Float
            ): Long {
                needScaleSmall = true
                isUpward = true
                return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy)
            }

            override fun clearView(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder
            ) {
                val itemViewType = viewHolder.itemViewType
                if (itemViewType != GridImageAdapter.TYPE_CAMERA) {
                    viewHolder.itemView.alpha = 1.0f
                    super.clearView(recyclerView, viewHolder)
                    mAdapter!!.notifyDataSetChanged()
                    resetState()
                }
            }
        })

        // 绑定拖拽事件
        mItemTouchHelper?.attachToRecyclerView(vb.recycler)


    }

    /**
     * 重置
     */
    private fun resetState() {
        if (mDragListener != null) {
            mDragListener!!.deleteState(false)
            mDragListener!!.dragState(false)
        }
        isUpward = false
    }


    private fun initPermission() {


        XXPermissions.with(this) // 申请安装包权限
            //.permission(Permission.REQUEST_INSTALL_PACKAGES)
            // 申请悬浮窗权限
            //.permission(Permission.SYSTEM_ALERT_WINDOW)
            // 申请通知栏权限
            //.permission(Permission.NOTIFICATION_SERVICE)
            // 申请系统设置权限
            //.permission(Permission.WRITE_SETTINGS)
            // 申请单个权限
//            .permission(Permission.RECORD_AUDIO) // 申请多个权限
//            .permission(Permission.READ_EXTERNAL_STORAGE) // 申请多个权限
//            .permission(Permission.WRITE_EXTERNAL_STORAGE) // 申请多个权限
            .permission(Permission.MANAGE_EXTERNAL_STORAGE) // 申请多个权限
            .permission(Permission.CAMERA) // 申请多个权限
//            .permission(Permission.Group.CALENDAR)
            .request(object : OnPermissionCallback {
                override fun onGranted(
                    permissions: List<String>,
                    all: Boolean
                ) {
                    if (all) {
                        ToastUtils.showShort("获取相机和内存卡权限成功")
                    } else {
                        ToastUtils.showShort("获取部分权限成功，但部分权限未正常授予")
                    }
                }

                override fun onDenied(
                    permissions: List<String>,
                    never: Boolean
                ) {
                    if (never) {
                        ToastUtils.showShort("被永久拒绝授权，请手动授予必须权限")
                        // 如果是被永久拒绝就跳转到应用权限系统设置页面
                        XXPermissions.startPermissionActivity(this@PostActivity, permissions)
                    } else {
                        ToastUtils.showShort("获取相机和内存卡权限失败")
                    }
                }
            })


    }


    override fun initClick() {
    }

    override fun initData() {
    }

    override fun initVM() {
    }

    inner class MyResultCallback(adapter: GridImageAdapter?) :
        OnResultCallbackListener<LocalMedia> {
        private val mAdapterWeakReference: WeakReference<GridImageAdapter?>
        override fun onResult(result: List<LocalMedia>) {
            for (media in result) {
                LogUtils.i(TAG, "是否压缩:" + media.isCompressed)
                LogUtils.i(TAG, "压缩:" + media.compressPath)
                LogUtils.i(TAG, "原图:" + media.path)
                LogUtils.i(TAG, "绝对路径:" + media.realPath)
                LogUtils.i(TAG, "是否裁剪:" + media.isCut)
                LogUtils.i(TAG, "裁剪:" + media.cutPath)
                LogUtils.i(TAG, "是否开启原图:" + media.isOriginal)
                LogUtils.i(TAG, "原图路径:" + media.originalPath)
                LogUtils.i(TAG, "Android Q 特有Path:" + media.androidQToPath)
                LogUtils.i(TAG, "宽高: " + media.width + "x" + media.height)
                LogUtils.i(TAG, "Size: " + media.size)
                // TODO 可以通过PictureSelectorExternalUtils.getExifInterface();方法获取一些额外的资源信息，如旋转角度、经纬度等信息
            }
            if (mAdapterWeakReference.get() != null) {
                mAdapterWeakReference.get()!!.setList(result)
                mAdapterWeakReference.get()!!.notifyDataSetChanged()
            }
            mAdapter?.setList(result)
            mAdapter?.notifyDataSetChanged()
        }

        override fun onCancel() {
            LogUtils.i(TAG, "PictureSelector Cancel")
        }

        init {
            mAdapterWeakReference = WeakReference(adapter)
        }
    }

}